package gsp420;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.util.Vector;

import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable
{
	/** the text that will be displayed in the game */
	private String m_text;
	protected Vector2D position = new Vector2D();
	
	EventHandler events;
	
	Entity m_player;
	
	Vector<Entity> m_entities = new Vector<Entity>();
	
	Vector<Vector2D> m_particleEffects = new Vector<Vector2D>();

	
	EventHandler getEventHandler()
	{
		return events;
	}
	
	/**
	 * @param a_text will be the text that will display in the panel ({@link GamePanel#m_text})
	 */
	public GamePanel(String a_text)
	{
		// initialization
		m_text = a_text;
		events = new EventHandler(this);
		addKeyListener(events);
		addMouseListener(events);
		addMouseMotionListener(events);
		// game loop
		Thread t = new Thread(this);
		t.start();
	}
	void generateWorld(int w, int h)
	{
		m_player = new Circle(Math.random()*w, Math.random()*h, 10);
		m_entities.add(m_player);
		Entity e;
		for(int i = 0; i < 10; ++i)
		{
			e = new Square(Math.random()*w, Math.random()*h, 10);
			e.v.set(1-Math.random()*2, 1-Math.random()*2);
			e.v.normalize();
			e.v.multiply(10);
			m_entities.add(e);
//			System.out.println(e.p.x+" "+e.p.y);
		}
	}
	public void paintComponent(Graphics g)
	{
//		super.paintComponents(g);	// will refresh the background
		if(m_entities.size() == 0)
		{
			generateWorld(getWidth(), getHeight());
		}
		g.setColor(Color.white);
		g.fillRect(0, 0, getWidth(), getHeight());
		g.setColor(Color.black);
		g.drawString(m_text, (int)position.x, (int)position.y);
		for(int i = 0; i < m_entities.size(); ++i)
		{
			m_entities.get(i).draw(g);
		}
		for(int i = 0; i < m_particleEffects.size(); ++i)
		{
			int x = (int)m_particleEffects.get(i).x;
			int y = (int)m_particleEffects.get(i).y;
			g.setColor(Color.GREEN);
			g.drawRect(x-1, y-1, 3, 3);
		}
	}
	
	public void update(double seconds)
	{
		for(int i = 0; i < m_entities.size(); ++i)
		{
			m_entities.get(i).update(seconds);
		}
		for(int a = 0; a < m_entities.size(); ++a)
		{
			for(int b = a+1; b < m_entities.size(); ++b)
			{
				Entity ea = m_entities.get(a);
				Entity eb = m_entities.get(b);
				if(ea.isCollidingWith(eb))
				{
					Vector2D particle = ea.p.sum(eb.p);
					particle.divide(2);
					m_particleEffects.add(particle);
				}
			}
		}
	}
	
	boolean running = true;
	
	public void run()
	{
		// keep track of the passage of time
		long now, then = System.currentTimeMillis();
		double passed;
		// game loop
		while(running)
		{
			// time calculations
			now = System.currentTimeMillis();
			passed = (double)((now-then)/1000.0);
			then = now;
			// update
			update(passed);
			// draw
			repaint();
			// really bad throttle code
			try{Thread.sleep(10);}catch(Exception e){}
		}
	}
	
	public String toString()
	{
		return m_text+"@"+position;
	}
	
	public void handleKeyEvent(KeyEvent e)
	{
//		System.out.println(e);
		if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
		{
			if(m_text.length() > 0)
			{
				m_text = m_text.substring(0, m_text.length()-1);
			}
		}
		else
		{
			char c = e.getKeyChar();
			if(c >= 0 && c <= 128)	// only add correctly displayable characters
			{
				m_text += e.getKeyChar();
			}
		}
		switch(e.getKeyCode())
		{
		case KeyEvent.VK_UP:	m_player.v.y--;	break;
		case KeyEvent.VK_LEFT:	m_player.v.x--;	break;
		case KeyEvent.VK_DOWN:	m_player.v.y++;	break;
		case KeyEvent.VK_RIGHT:	m_player.v.x++;	break;
		}
	}
	public void setPosition(int x, int y)
	{
		position.x = x;
		position.y = y;
	}
}
